package com.example.managerment.filter;
import com.example.managerment.module.vo.ResultVO;
import com.example.managerment.util.JwtUtil;
import com.example.managerment.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class UriFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 拦截url,如果url是login,直接放行，否则拉杰token
     * @param request
     * @param response
     * @param filterChain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        /**
         * 拦截url,如果url是login,直接放行，否则拉杰token
         */
        String uri = request.getRequestURI();
        if(uri.indexOf("/login") == 0 || uri.indexOf("/syslogin") == 0){
            filterChain.doFilter(request,response);
        }else{
            /**
             * 从请求头获取token，如果token没有过期且真实
             *  从缓存中读取用户身份写道上下文中
             *  生成新的token并缓存token
             *  将token添加到响应头，响应给客户端
             *  将请求转发给控制器
             * 否则拒绝访问
             */
            boolean access = true;//允许访问
            //从请求头获取token
            String accessToken = request.getHeader("token");
            //如果token没有过期
            if(!jwtUtil.isExpires(accessToken)){
                //从token中获取用户id
                String username = jwtUtil.getUserName(accessToken);
                //从缓存中读取token
                String validityToken = redisUtil.getToken(username);
                //如果token真实
                if(jwtUtil.validityToken(accessToken,validityToken)){
                    //生成token
                    String token = jwtUtil.generateToken(username);
                    //保存在redis中
                    redisUtil.save(username,token);
                    //从redis中读取用户身份，并将用户身份写入上下文
                    Authentication authentication = redisUtil.getAuthentication(username);
                    SecurityContextHolder.getContext().setAuthentication(authentication);

                    //添加响应头
                    response.setHeader("token",token);
                    //验证通过，转发请求
                    filterChain.doFilter(request,response);
                }else {
                    //拒绝访问
                    access = false;
                }
            }else {
                //拒绝访问
                access = false;
            }
            if(!access){
                ResultVO resultVO = new ResultVO("用户未登录");
                resultVO.out(response);
            }
        }

    }
}
